<#--DAO-->
<#-- 传入参数 Func func, DataTable table --> 
package ${func.javaPkg}.dao;

import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
import com.vecspace.data.model.FilterColumn;
import com.vecspace.data.model.Pagination;
import com.vecspace.database.dao.AbstractDao;
import com.vecspace.database.dao.DaoUtil;
import com.vecspace.database.model.QueryResultAggregation;
import com.vecspace.database.model.QuerySQL;
import com.vecspace.utils.Assert;
import ${func.javaPkg}.pojo.${table.className};
import ${func.javaPkg}.pojo.${table.className}Ex;
import ${func.javaPkg}.pojo.${table.className}Stats;

/** ${table.tableCaption!},操作数据库的dao类
 * @template dayu-code-builder
 * @author ${author}
 * @reviewer 
 * @createTime ${nowTime}
 * @version 1.0
 */
@Repository("${sysName}_${table.beanName}Dao")
public class ${table.className}Dao extends AbstractDao {
    /** 根据ID查询 ${table.TableDesc!}
     * @param ${table.idVarName}   主键值
     * @return ${table.className}
     * @throws Exception
     * @author ${author}
     * @reviewer 
     * @createTime ${nowTime}
     */
    public ${table.className} get${table.className}(${table.idPropJavaType} ${table.idVarName}) throws Exception {
        ${table.className} ${table.beanName} = null;
        if (${table.idVarName} != null) {
            ${table.beanName} = dao.queryObject(${table.className}.class, ${table.idVarName});
            this.dao.evict(${table.beanName});
        }
        return ${table.beanName};
    }

<#if parentColumn??>
    /**根据父节点id获取子节点
     *
     * @param parentId
     * @return
     * @throws Exception
     */
    public List<${table.className}> getChild${table.className}List(<#if foreignColumn??>${foreignColumn.javaType} ${foreignColumn.varName}, </#if>${parentColumn.javaType} ${parentColumn.varName}) throws Exception {
<#if foreignColumn??>
        List<${table.className}> ${table.beanName}List = dao.queryObjectList("from ${table.className} where ${foreignColumn.varName}=?0 and ${parentColumn.varName}=?1 order by ${(table.orderColumn.varName)!'ID desc'}", new Object[]{${foreignColumn.varName}, ${parentColumn.varName}});
<#else>
        List<${table.className}> ${table.beanName}List = dao.queryObjectList("from ${table.className} where ${parentColumn.varName}=?0 order by ${(table.orderColumn.varName)!'ID desc'}", new Object[]{${parentColumn.varName}});
</#if>
        return ${table.beanName}List;
    }

    /**根据 ${parentColumn.columnCaption} 获取${table.tableCaption}记录条数
     *
     * @param ${parentColumn.varName}  ${parentColumn.columnCaption}
     * @return
     * @throws Exception
     * @author ${author}
     * @reviewer
     * @createTime ${nowTime}
     */
    public int get${table.className}CountBy${parentColumn.propNameTrimId}(${parentColumn.javaType} ${parentColumn.varName}) throws Exception {
        int rcount = dao.queryInt("select count(*) from ${table.tableName} where ${parentColumn.columnName}=?0 order by ${(table.orderColumn.varName)!'ID'}", new Object[]{${parentColumn.varName}});
        return rcount;
    }
</#if>

<#if foreignColumn??>
    /**根据 ${foreignColumn.columnCaption} 获取${table.tableCaption}列表
     *
     * @param ${foreignColumn.varName} ${foreignColumn.columnCaption}
     * @return
     * @throws Exception
     * @author ${author}
     * @reviewer
     * @createTime ${nowTime}
     */
    public List<${table.className}> get${table.className}ListBy${foreignColumn.propNameTrimId}(${foreignColumn.javaType} ${foreignColumn.varName}) throws Exception {
        List<${table.className}> ${table.beanName}List = dao.queryObjectList("from ${table.className} where ${foreignColumn.varName}=?0 order by ${(table.orderColumn.varName)!'ID'}", new Object[]{${foreignColumn.varName}});
        return ${table.beanName}List;
    }

    /**根据 ${foreignColumn.columnCaption} 获取${table.tableCaption}记录条数
     *
     * @param ${foreignColumn.varName}  ${foreignColumn.columnCaption}
     * @return
     * @throws Exception
     * @author ${author}
     * @reviewer
     * @createTime ${nowTime}
     */
    public int get${table.className}CountBy${foreignColumn.propNameTrimId}(${foreignColumn.javaType} ${foreignColumn.varName}) throws Exception {
        int rcount = dao.queryInt("select count(*) from ${table.tableName} where ${foreignColumn.columnName}=? order by ${(table.orderColumn.varName)!'ID'}", new Object[]{${foreignColumn.varName}});
        return rcount;
    }
</#if>

    /**根据属性名获取字段值
     * @param ${table.idVarName} 记录id
     * @param propName 属性名
     * @return
     * @throws Exception
     * @author ${author}
     * @reviewer
     * @createTime ${nowTime}
     */
    public Object getValueByProp(${table.idPropJavaType} ${table.idVarName}, String propName) throws Exception {
    	return this.getValueByPropName(${table.className}.class, ${table.idVarName}, propName);
    }

    /**根据id更新指定字段的值（根据propName从pojo获取字段名）
     * @param ${table.idVarName} 记录id
     * @param propName 属性名
     * @param value 属性值
     * @throws Exception
     * @author ${author}
     * @reviewer
     * @createTime ${nowTime}
     */
    public void updateValueByProp(${table.idPropJavaType} ${table.idVarName}, String propName, Object value) throws Exception {
    	this.updateValueByPropName(${table.className}.class, ${table.idVarName}, propName, value);
    }

    /** 插入或修改 ${table.tableDesc!}
     * @param item 要保存的对象
     * @return void
     * @throws Exception
     * @author ${author}
     * @reviewer
     * @createTime ${nowTime}
     */
    public void save${table.className}(${table.className} item) throws Exception {
        dao.saveOrUpdateObject(item);
        dao.evict(item);
    }

<#if isTree==true && parentColumn??>
    /**更改 自己所属的父节点
     *
     * @param ${table.idVarName} ${table.tableName}.${table.idVarName}
     * @param ${parentColumn.varName}New 新的 ${parentColumn.columnCaption}
     * @throws Exception
     * @author ${author}
     * @reviewer
     * @createTime ${nowTime}
     */
    public void change${parentColumn.propNameTrimId}(${table.idPropJavaType} ${table.idVarName}, ${parentColumn.javaType} ${parentColumn.varName}New) throws Exception {
        String sql = "update ${table.tableName} set ${parentColumn.columnName}=? where ${table.idColumn.columnName}=?";
        dao.updateDataRowBySql(sql, new Object[]{${parentColumn.varName}New, ${table.idVarName}});
    }
</#if>


    /** 根据ID删除 ${table.tableDesc!}
     * @param ${table.idVarName}  主键值
     * @return void
     * @throws Exception
     * @author ${author}
     * @reviewer
     * @createTime ${nowTime}
     */
    public void delete${table.className}(${table.idPropJavaType} ${table.idVarName}) throws Exception {
        if (${table.idVarName} != null) {
            dao.deleteObject(${table.className}.class, ${table.idVarName});
        }
    }
    
    /**根据多个查询条件执行分页查询 （可以分页，不分页，以及同时进行聚合统计查询，,聚合统计查询是对所有满足条件的数据进行聚合，而不仅仅是当前页的数据）
     * 
     <#if foreignColumn??>* @param ${foreignColumn.varName} ${foreignColumn.caption!} </#if>
     <#if useRecurseQuery==true>* @param recursion 是否递归查询所有下级数据 </#if>
     * @param filterColumns 查询条件
     * @param pageIndex 第几页 从1开始
     * @param pageSize 每页显示的数据条数,负数表示不分页
     * @param sortColumn 排序字段（属性名或者字段名）
     * @param sortOrder 排序方式 DESC ASC
     * @return
     * @throws Exception
     * @author ${author}
     * @reviewer
     * @createTime ${nowTime}
     */
    public QueryResultAggregation<${table.className}Ex, ${table.className}Stats> get${table.className}ExListAndStats(<#rt>
        <#lt><#if foreignColumn?? >${foreignColumn.javaType} ${foreignColumn.varName}, </#if><#rt>
        <#lt><#if useRecurseQuery==true>boolean recursion, </#if><#rt>
      <#lt>List<FilterColumn> filterColumns,
        int pageIndex, int pageSize, String sortColumn, String sortOrder) throws Exception {

<#if useRecurseQuery==true>
        QuerySQL querySql;
        if(recursion){//根据树形结构递归查询所有下级数据
            querySql = DaoUtil.getQuerySql(this.getClass(), "querysqlRecursion");
            Assert.throwz(querySql != null && querySql.valid(), "Employee.sql.xml中<sql id='querysqlRecursion'>没有定义SQL,或者定义的格式不正确");
        }else{
            querySql = DaoUtil.getQuerySql(this.getClass(), "querysql");
            Assert.throwz(querySql != null && querySql.valid(), "Employee.sql.xml中<sql id='querysql'>没有定义SQL,或者定义的格式不正确");
        }
<#else>
        QuerySQL querySql = DaoUtil.getQuerySql(this.getClass(), "querysql");
        Assert.throwz(querySql != null && querySql.valid(), "Employee.sql.xml中<sql id='querysql'>没有定义SQL,或者定义的格式不正确");
</#if>
<#if foreignColumn??>
  <#if (dbType == "pgsql" || dbType == "mysql")>
        //设置sql中固化条件的查询值
        querySql.setSqlParameterValues(new Object[]{${foreignColumn.varName}});
  </#if>
        //增加查询条件和值。将filterColumns中的ColumnName进行处理，如果值为propName，则替换为ColumnName
        querySql.addQueryFilter(filterColumns);
  <#if dbType == "oracle">
        //设置sql中固化条件的查询值
        querySql.setSqlParameterValues(new Object[]{${foreignColumn.varName}});
  </#if>
</#if>

        if(StringUtils.isNotBlank(sortColumn)) {
            querySql.setOrderby(sortColumn, sortOrder);
        }
        QueryResultAggregation<${table.className}Ex, ${table.className}Stats> ${table.beanName}List = dao.queryEntitiesAndAggregate(${table.className}Ex.class, ${table.className}Stats.class, querySql, new Pagination(pageIndex, pageSize));

        return ${table.beanName}List;
    }
}
